package edu.friday.service.impl;

import edu.friday.common.constant.UserConstants;
import edu.friday.common.result.TableDataInfo;
import edu.friday.model.SysUser;
import edu.friday.model.SysUserRole;
import edu.friday.model.vo.SysUserVO;
import edu.friday.repository.SysUserRepository;
import edu.friday.repository.SysUserRoleRepository;
import edu.friday.service.SysUserService;
import edu.friday.utils.BeanUtils;
import edu.friday.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Service
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    SysUserRepository sysUserRepository;
    @Autowired
    SysUserRoleRepository sysUserRoleRepository;

    @Override
    public TableDataInfo selectUserList(SysUserVO user, Pageable page) {
        SysUser sysUser=new SysUser();
        BeanUtils.copyPropertiesIgnoreEmpty(user,sysUser);
        sysUser.setDelFlag("0");
        ExampleMatcher exampleMatcher=ExampleMatcher.matching()
                .withMatcher("userName",ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("phoneNumber",ExampleMatcher.GenericPropertyMatchers.contains());
        Example<SysUser> example=Example.of(sysUser,exampleMatcher);
        Page<SysUser> rs=sysUserRepository.findAll(example,page);
        return TableDataInfo.success(rs.toList(),rs.getTotalElements());
    }

    @Override
    public String checkUserNameUnique(String userName) {
        SysUser sysUser=new SysUser();
        sysUser.setUserName(userName);
        return count(sysUser);
    }

    private String count(SysUser sysUser) {
        Example<SysUser> example=Example.of(sysUser);
        Long count=sysUserRepository.count(example);
        if (count>0){
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkPhoneUnique(SysUserVO userVO) {
        SysUser sysUser=new SysUser();
        BeanUtils.copyProperties(userVO,sysUser);
        return checkUnique(sysUser);
    }

    private String checkUnique(SysUser sysUser) {
        Long userId= StringUtils.isNull(sysUser.getUserId())? -1L: sysUser.getUserId();
        Example<SysUser> example=Example.of(sysUser);
        SysUser info=findOne(example);
        if (StringUtils.isNotNull(info)&&info.getUserId().longValue()!=userId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    private SysUser findOne(Example<SysUser> example) {
        List<SysUser> list=sysUserRepository.findAll(example, PageRequest.of(0,1)).toList();
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    @Override
    public String checkEmailUnique(SysUserVO userVO) {
        SysUser sysUser=new SysUser();
        BeanUtils.copyProperties(userVO,sysUser);
        return checkUnique(sysUser);
    }

    @Override
    @Transactional
    public boolean insertUser(SysUserVO userVO) {
        SysUser sysUser=new SysUser();
        BeanUtils.copyProperties(userVO,sysUser);
        sysUser.setDelFlag("0");
        sysUserRepository.save(sysUser);
        userVO.setUserId(sysUser.getUserId());
        insertUserRole(userVO);
        return null != sysUser.getUserId();
    }

    @Override
    @Transactional
    public int deleteUserByIds(Long[] userIds) {
        return sysUserRepository.deleteUserByIds(userIds);
    }

    @Override
    @Transactional
    public boolean updateUser(SysUserVO userVO) {
        Long userId= userVO.getUserId();
        Optional<SysUser> op=sysUserRepository.findById(userId);
        if (!op.isPresent()) {
            return false;
        }
        sysUserRepository.deleteUserRoleByUserId(userId);
        SysUser sysUser=op.get();
        BeanUtils.copyPropertiesIgnoreNull(userVO,sysUser);
        sysUserRepository.save(sysUser);
        insertUserRole(userVO);
        return null!=sysUser.getUserId();
    }

    @Override
    public SysUser selectUserById(Long userId) {
        SysUser sysUser=new SysUser();
        sysUser.setUserId(userId);
        sysUser.setDelFlag("0");
        return sysUserRepository.findOne(Example.of(sysUser)).get();
    }

    @Override
    public void insertUsers(SysUserVO userVO) {
        SysUser sysUser=new SysUser();
        sysUser.setUserName(userVO.getUserName());
        sysUser.setEmail(userVO.getEmail());
        sysUser.setPhonenumber(userVO.getPhoneNumber());
        sysUser.setNickName(userVO.getNickName());
        sysUserRepository.save(sysUser);
    }

    @Override
    public SysUser selectUserByUserName(String userName) {
        SysUser user=new SysUser();
        user.setUserName(userName);
        user.setDelFlag("0");
        Example<SysUser> example=Example.of(user);
        return findOne(example);
    }


    @Transactional
    public int insertUserRole(SysUserVO userVO) {
        Long[] roles=userVO.getRoleIds();
        if (StringUtils.isNull(roles)|| roles.length==0) {
            return 0;
        }
        SysUserRole sysUserRole=new SysUserRole();
        Long userId = userVO.getUserId();
        for (Long roleId : roles) {
            sysUserRole.setRoleId(roleId);
            sysUserRole.setUserId(userId);
        }
        sysUserRoleRepository.save(sysUserRole);
        return 1;
    }



}
